iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
自我挑戰組

後端新手PHP+Laravel筆記系列 第 11

[Day11]PHP函數01

  • 分享至 

  • xImage
  •  

PHP函數

自定義函數

函數可用以下語法來定義

<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "Example function.\n";
    return $retval;
}
?>

函數不需要在使用之前被定義,除非是函數是有條件被定義時,才必須在使用前定義

舉以下範例

  1. 有條件的函數:
<?php

$makefoo = true;

/* 不能在此處調用foo()函數,    
 因為它還不存在,但可以調用bar()函數。*/

bar();

if ($makefoo) {
  function foo()
  {
    echo "I don't exist until program execution reaches me.\n";
  }
}

/* 現在可以安全調用函數 foo()    
   因為 $makefoo 值為真true */

if ($makefoo) foo();

function bar()
{
  echo "I exist immediately upon program start.\n";
}

?>
  1. 函數中的函數
<?php
function foo()
{
  function bar()
  {
    echo "I don't exist until foo() is called.\n";
  }
}

/* 現在還不能調用 bar() 函數,因為它還不存在 */

foo();

/* 現在可以調用 bar() 函數了,因為 foo() 函數的執行使得 bar() 函數變為已定義的函數 */

bar();

?>

PHP 中的所有函數和類都具有全局作用域,可以定義在一個函數之內而在之外調用,反之亦然。
PHP 不支持函數重載,也不可能取消定義或者重定義已聲明的函數。

還有遞迴函數,也就是自己呼叫自己

舉個費氏數列的例子(從0,1開始,後面的數是前兩個數相加)

<?php
function fib($n)
{
    if($n == 0) return 0;
    if($n == 1) return 1;
    return fib($n-1) + fib($n - 2);
}

for($i = 0; $i <= 5; $i++){
    echo fib("$i ");
}

// outputs
// 0,1,1,2,3,5

注意: 但是要避免遞歸函數/方法調用超過 100-200 層,因為可能會使堆積崩潰從而使當前腳本終止。無限遞歸可視為編程錯誤


函數的參數

通過給予函數參數,傳遞訊息給函數,可以放入多個參數用逗號分隔,也可以設置參數默認的值。

1. 向函數傳遞array:

<?php
function takes_array($nums)
{
    echo '$nums[0] + $nums[1] = ', $nums[0] + $nums[1];
}

從php8開始參數尾巴逗號是會被忽略的

2. 使用尾巴逗號

<?php
function takes_many_args(
    $first_name,
    $last_name,
    $age,
    $gender = 1,
    $cellphone = null, // 在 8.0.0 之前,尾部逗號是不允许的。
)
{
    // ...
}
?>

從 PHP 8.0.0 開始,不推薦在可選參數之後傳遞強制參數。 這通常可以通過刪除默認值來解決。 此規則的一個例外是 Type $param = null 形式的參數,其中 null 默認值使類型隱式可為空。 這種用法仍然被允許,但建議改用顯式可為空類型。

3. 在強制參數之後傳遞可選參數

<?php
function foo($a = [], $b) {} // 之前
function foo($a, $b) {}      // 之後

function bar(A $a = null, $b) {} // 同時可用
function bar(?A $a, $b) {}       // 官方推薦
?>

4. 在函數中使用默認參數

PHP 還允許使用數組 array 和特殊類型 null 作為默認參數。

<?php
function makecoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>

// outputs
// Making a cup of cappuccino.
// Making a cup of .
// Making a cup of espresso.

5. 函數默認參數的不正確用法

默認值必須是常量表達式,不能是,如變量,類成員,或者函數調用等。 注意當使用默認參數時,任何默認參數必須放在任何非默認參數的右側;否則,函數將不會按照預期的情況工作。

<?php
function makeyogurt($type = "acidophilus", $flavour)
{
    return "Making a bowl of $type $flavour.\n";
}

echo makeyogurt("raspberry");   // won't work as expected
?>

// Warning: Missing argument 2 in call to makeyogurt()

6. 函數默認參數正確用法

<?php
function makeyogurt($flavour, $type = "acidophilus")
{
    return "Making a bowl of $type $flavour.\n";
}

echo makeyogurt("raspberry");   // works as expected
?>

// outputs
// Making a bowl of acidophilus raspberry.

7. 使用 ... 來訪問變量參數

PHP 在用戶自定義函數中支持可變數量的參數列表。由 ... 語法實現。

包含 ... 的參數,會轉換為指定參數變量的一個數組(類似字典),以下示例:

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

// 10

8. 使用...來傳遞參數

<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])."\n";

$a = [1, 2];
echo add(...$a);
?>

// 3
// 3

9. 輸入提示的變量參數

<?php
function total_intervals($unit, DateInterval ...$intervals) { // 必須傳遞DateInterval類的參數
    $time = 0;
    foreach ($intervals as $interval) {
        $time += $interval->$unit;
    }
    return $time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo total_intervals('d', $a, $b).' days';

// This will fail, since null isn't a DateInterval object.
echo total_intervals('d', null);
?>

// outputs
// 3 days
// Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, 
// null given, called in - on line 14 and defined in - on line 2

命名函數

PHP 8.0.0 開始引入了命名參數作為現有位置參數的擴展。命名參數允許根據參數名而不是參數位置向函數傳參。這使得參數的含義自成體系,參數與順序無關,並允許任意跳過默認值。

命名參數通過在參數名前加上冒號來傳遞。允許使用保留關鍵字作為參數名。參數名必須是一個標識符,不允許動態指定。

10. 命名參數語法

<?php
function myFunction($paramName){
    echo $paramName;
}
myFunction(paramName: $value);  // $value指定給予paramName這個參數
array_foobar(array: $value);

// NOT supported.
function_name($variableStoringParamName: $value); // 不能動態指定
?>

11. 通過位置傳參與命名參數的對比

<?php
// 使用順序傳遞:
array_fill(0, 100, 50);

// 使用命名參數:
array_fill(start_index: 0, count: 100, value: 50);
?>

順序不重要,下面輸出跟上面一樣

<?php
array_fill(value: 50, count: 100, start_index: 0);
?>

12. 不可多次傳遞給同一個參數

<?php
function foo($param) { ... }

foo(param: 1, param: 2);
// Error: Named parameter $param overwrites previous argument
foo(1, param: 2);
// Error: Named parameter $param overwrites previous argument
?>

資料來源: https://www.php.net/


上一篇
[Day10]PHP判斷式03
下一篇
[Day12]PHP 可變函數及回傳值
系列文
後端新手PHP+Laravel筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言